package com.gexin.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.gexin.common.AppGlobal;
import com.gexin.common.cache.CacheUtils;
import com.gexin.common.cache.RedisKeyConst;
import com.gexin.common.model.ApiResponse;
import com.jfinal.kit.PropKit;
import com.jfinal.log.Log;
import com.jfinal.weixin.sdk.kit.IpKit;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  Mo信通短信API
 * @author xu
 */
public class MoSmsUtils {
    private static String Mo_api_url = PropKit.get("MO_api_url");
    private static String Def_Sms_Signature = PropKit.get("MO_sms_signature");

	public static String Mo_Code_Username = "gxxx001";//验证码账号（免审）
    public static String Mo_Notice_Username = "gxxx002";//通知账号
    public static String Mo_Marketing_Username = "gxxx003";//
    public static String Mo_Pwd = "02d382745ace075251a23e9991757d32";//会员营销账号加密码（和密码关联）
	private static Log log = Log.getLog(MoSmsUtils.class);

	public static String code_message_text = "【%s】您的验证码是%s，请于十分钟内正确输入。";

    /**
     *  验证码短信发送接口（默认签名）
     * @param phone     手机号，多个逗号隔开
     * @param code      验证码
     * @param content   短信内容（不包括code）
     * @return
     */
    public static ApiResponse SendCode(String phone, String code, HttpServletRequest  req){
        return SendCode(phone,Def_Sms_Signature,code,req);
    }

    /**
     *  验证码短信发送接口
     * @param phone     手机号，多个逗号隔开
     * @param code      验证码
     * @param signature 短信签名
     * @param content   短信内容（不包括code）
     * @return
     */
    public static ApiResponse SendCode(String phone, String signature, String code, HttpServletRequest  req){
        String content = String.format(code_message_text,signature,code);
        return SendCodeContent(phone,code,content,req);
    }

    /**
     *  验证码短信发送接口(通用短信模版)
     * @param phone     手机号，多个逗号隔开
     * @param code      验证码（用于记录日志）
     * @param content   短信内容
     * @return
     */
    public static ApiResponse SendCodeContent(String phone, String code, String content, HttpServletRequest  req){
        String key = RedisKeyConst.Message_Send+phone;

        ApiResponse cmd =null;
        //限制发送频率1分钟
        if(CacheUtils.exists(key)==true){
            cmd = new ApiResponse(false, "发送时间太短了！");
            return cmd ;
        }
        if(StringUtil.isEmpty(phone)==false){
            //限制验证码发送条数，一天最多5条
            String date = DateUtil.getDate("yyyy-MM-dd");
            Integer size = CacheUtils.get(date+key);
            if(size==null){
                CacheUtils.set(date+key,1, RedisKeyConst.day);
            }else{
                if(!AppGlobal.dev_Mode){
                    if(size>=5){
                        log.warn(String.format("短信发送异常：号码:%s,请求发送次数:%s次，Ip:%s", phone,size, IpKit.getRealIpV2(req)));
                        size++;
                        CacheUtils.set(date+key,size, RedisKeyConst.day);
                        return  new ApiResponse(false,"验证码一天最多发送5次");
                    }
                }
                size++;
                CacheUtils.set(date+key,size, RedisKeyConst.day);
            }


            if(AppGlobal.dev_Mode){
                log.info("测试模式 发送验证码0000");
                code="0000";
            }
            if(batchSend(Mo_Code_Username,Mo_Pwd,phone, content)){
                //限制发送频率1分钟
                CacheUtils.set(key, phone, RedisKeyConst.Message_Send_time);
                //把验证码存到redis 里面去
                CacheUtils.set(RedisKeyConst.Message_Code+phone, code, RedisKeyConst.Message_Code_time);
                log.info("发送验证码为："+phone+":"+code);
                cmd = new ApiResponse(true, "发送成功！");
            }else{
                cmd = new ApiResponse(true, "发送失败请稍后再试！");
            }
        }else{
            cmd =(new ApiResponse(false, "参数错误！"));
        }
        return cmd ;
    }

    /**
     * 检测验证码是否正确
     * @param phone    手机号码
     * @param code   验证码
     * @return
     */
    public static boolean  CheckCode(String phone,String code){
        String perincode = CacheUtils.get(RedisKeyConst.Message_Code+phone);
        if(perincode!=null && code.equals(perincode)){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 清除验证码
     * @param phone    手机号码
     * @return
     */
    public static void  delCode(String phone){
        CacheUtils.del(RedisKeyConst.Message_Code+phone);
    }

    /**
     *  通知短信发送接口
     * @param phone     手机号，多个逗号隔开
     * @param content   发送内容
     * @return
     */
    public static Boolean SendNotice(String phone,String content){
        return batchSend(Mo_Notice_Username,Mo_Pwd,phone,content);
    }

    /**
     *  会员营销短信发送接口
     * @param phone     手机号，多个逗号隔开
     * @param content   发送内容
     * @return
     */
    public static Boolean SendMarket(String phone,String content){
        return batchSend(Mo_Marketing_Username,Mo_Pwd,phone,content);
    }


    /**
     *  短信发送接口
     * @param username  账号
     * @param pwd       加密码
     * @param phone     手机号，多个逗号隔开
     * @param content   发送内容
     * @return
     */
    public static Boolean batchSend(String username,String pwd,String phone,String content){
        //如果是开发者模式  直接返回
//        if(AppGlobal.dev_Mode){
//            return true;
//        }
        String url = Mo_api_url+"httpBatchSend";
        Map<String,String> params = new HashMap<>();
        params.put("username",username);
        params.put("pwd",pwd);
        params.put("mobile",phone);
        params.put("content",content);
        String ret = post(url,params);
        JSONObject obj = JSONObject.parseObject(ret);
        if (obj.getInteger("code")==0){
            return true;
        }else {
            log.info(phone+"短信发送失败："+content);
            log.error("Mo信通短信发送失败"+obj.getInteger("code")+"："+obj.getString("msg"));
            return false;
        }
    }

    /**
     * 查询余额
     * @return
     */
	public static String queryBalance(String username,String pwd){
        String url = Mo_api_url+"queryBalance";
//	    String username = "gxxx001";
//	    String pwd = "4dae6489da13cc5285058c9124346ef0";
        Map<String,String> params = new HashMap<>();
        params.put("username",username);
        params.put("pwd",pwd);
        String ret = post(url,params);
        return ret;
    }

    /*	http请求	*/
    public static String post(String url,Map<String, String> param){
        String body = null;
        HttpClient httpClient = new DefaultHttpClient();
        try {
            // Post请求
            HttpPost httppost = new HttpPost(url);
            // 设置参数
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            for (String key : param.keySet()) {
                params.add(new BasicNameValuePair(key, param.get(key)));
            }
            httppost.setEntity(new UrlEncodedFormEntity(params,"utf-8"));
            // 发送请求
            HttpResponse httpresponse = httpClient.execute(httppost);
            // 获取返回数据
            HttpEntity entity = httpresponse.getEntity();
            if (entity != null) {
                body = EntityUtils.toString(entity);
                entity.consumeContent();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return body;
    }
}
